﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DevelopTool.Bll.LocalDbBlls;
using DevelopTool.Common;
using DevelopTool.Common.ILSpy;
using DevelopTool.Model.AssemblyyModels;
using DevelopTool.Model.CommonModels;
using LiteDB;
using Sunny.UI;

namespace DevelopTool.Bll.AssemblyyBlls
{
    public class AssemblyyBll : BaseBll
    {
        private ILSpyHelper iLSpyHelper;

        public AssemblyyBll()
        {
            iLSpyHelper = new ILSpyHelper();

            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Assemblyy>();
                col.EnsureIndex(x => x.Sign);
                col.EnsureIndex(x => x.Id);
            }
        }


        /// <summary>
        /// 搜索程序集内容
        /// </summary>
        /// <param name="assemblyPath">程序集路径</param>
        /// <param name="keywords">关键字集合</param>
        /// <param name="ignoreCase">是否区分大小写 true=区分大小写</param>
        /// <returns></returns>
        public List<Tuple<string,Assemblyy>> SearchAssemblyContent(string assemblyPath,List<string> keywords,bool ignoreCase)
        {
            try
            {
                using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
                {
                    var col = db.GetCollection<Assemblyy>();

                    string sign = new FileInfo(assemblyPath).CRC32();//获取文件标记

                    Assemblyy assemblyy = col.FindOne(x => x.Sign == sign && x.ContentsByte != null);//每次都从本地数据库查下是否存在
                    if(assemblyy == null)
                    {
                        var classList = this.iLSpyHelper.GetClassListByAssembly(assemblyPath);//反编译程序集并获取类集合

                        if(classList == null || classList.Count <= 0) return new List<Tuple<string,Assemblyy>>();//没有内容就不管了

                        assemblyy = new Assemblyy()
                        {
                            Sign = sign,
                            Path = assemblyPath,
                            Contents = classList.Select(it => new AssemblyyContent() { TypeName = it.Item1,Text = it.Item2 }).ToList(),
                            Name = Path.GetFileName(assemblyPath),
                        };

                        assemblyy = this.Insert(assemblyy);//缓存到本地数据库
                    }

                    //解压缩内容
                    if(assemblyy.Contents == null || assemblyy.Contents.Count <= 0)
                    {
                        assemblyy.Contents = assemblyy.ContentsByte.ByteToObject_Decompress<List<AssemblyyContent>>();
                    }

                    assemblyy.Path = assemblyPath;//始终都设置为当前的程序集路径

                    List<Tuple<string,Assemblyy>> list = new List<Tuple<string,Assemblyy>>();

                    if(keywords == null || keywords.Count <= 0)//没有关键字就直接返回反编译的内容
                    {
                        list.Add(new Tuple<string,Assemblyy>(string.Empty,assemblyy));
                        return list;
                    }
                    else
                    {
                        //是否区分大小写
                        StringComparison comparisonType = ignoreCase ? StringComparison.CurrentCulture : StringComparison.OrdinalIgnoreCase;

                        foreach(string keyword in keywords)//根据关键字搜索
                        {
                            //关键字匹配程序集名称                          
                            if(Path.GetFileName(assemblyy.Path).IndexOf(keyword,comparisonType) > -1)
                            {
                                var assemblyyClone = assemblyy.CloneObj();//克隆下对象
                                assemblyyClone.Contents = new List<AssemblyyContent>() {
                                new AssemblyyContent()
                                };

                                assemblyyClone.MatchType = "程序集名";
                                list.Add(new Tuple<string,Assemblyy>(keyword,assemblyyClone));
                            }

                            //关键字匹配类名                          
                            var contentListName = assemblyy.Contents.FindAll(it => !string.IsNullOrEmpty(it.TypeName) && it.TypeName.IndexOf(keyword,comparisonType) > -1).ToList();
                            if(contentListName.Count > 0)
                            {
                                var assemblyyClone = assemblyy.CloneObj();
                                assemblyyClone.Contents = contentListName.Select(it => new AssemblyyContent
                                {
                                    TypeName = it.TypeName
                                }).ToList();

                                assemblyyClone.MatchType = "类名";
                                list.Add(new Tuple<string,Assemblyy>(keyword,assemblyyClone));
                            }

                            //关键字匹配内容
                            var contentListText = assemblyy.Contents.FindAll(it => !string.IsNullOrEmpty(it.Text) && it.Text.IndexOf(keyword,comparisonType) > -1).ToList();
                            if(contentListText.Count > 0)
                            {
                                var assemblyyClone = assemblyy.CloneObj();
                                assemblyyClone.Contents = contentListText;
                                assemblyyClone.MatchType = "内容";
                                list.Add(new Tuple<string,Assemblyy>(keyword,assemblyyClone));
                            }

                        }
                        return list;
                    }
                }
            }
            catch(Exception ex)
            {
                Assemblyy assemblyy = new Assemblyy()
                {
                    Path = assemblyPath,
                    Contents = new List<AssemblyyContent>() { new AssemblyyContent { Text = ex.Message } }
                };
                return new List<Tuple<string,Assemblyy>>() { new Tuple<string,Assemblyy>(string.Empty,assemblyy) };
            }
        }


        /// <summary>
        /// 停止反编译
        /// </summary>
        public void StopDecompile()
        {
            this.iLSpyHelper.Status = false;
        }


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="ocr"></param>
        private Assemblyy Insert(Assemblyy assemblyy)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Assemblyy>();

                if(!col.Exists(it => it.Sign == assemblyy.Sign) && assemblyy.Contents.Count > 0)//缓存过的就不存了
                {
                    assemblyy.ContentsByte = assemblyy.Contents.ObjectToByte_Compress();//压缩内容
                    assemblyy.Contents = null;
                    col.Insert(assemblyy);
                }
                return assemblyy;
            }
        }


        private void Update(Assemblyy assemblyy)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Assemblyy>();

                col.Update(assemblyy);
            }
        }


        /// <summary>
        /// 清除缓存
        /// </summary>
        public void ClearCache()
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Assemblyy>();

                col.Delete(it => it.Id >= 0);
            }
        }


        public bool Delete(List<int> ids)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Assemblyy>();

                return col.Delete(it => ids.Contains(it.Id)) > 0 ? true : false;
            }
        }

        public void SetRemark(int id,string remark)
        {

        }

        public ManageMenu Get(int id)
        {
            return new ManageMenu();
        }


    }
}
